/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package transervfx.Vista;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import jfxtras.labs.scene.control.CalendarTextField;
import recursos.img.pathRecusosIMG;
import transervfx.Dato.Entidad.Agencia;
import transervfx.Dato.Entidad.Cliente;
import transervfx.Dato.Entidad.Domicilio;
import transervfx.Dato.Entidad.Encomienda;
import transervfx.Dato.Entidad.Externa;
import transervfx.Dato.Entidad.Interna;
import transervfx.Dato.Entidad.Lugar;
import transervfx.Dato.Entidad.LugarPersonalFrecuente;
import transervfx.Dato.Entidad.TipoEncomienda;
import transervfx.Logica.GestorAgencia;
import transervfx.Logica.GestorCliente;
import transervfx.Logica.GestorEncomienda;
import transervfx.Logica.GestorServicio;
import transervfx.Logica.GestorTipoServicio;
import transervfx.Vista.CompPersonalizado.Servicio.ClienteComp;
import transervfx.Vista.CompPersonalizado.Servicio.LugarComp;
import transervfx.Vista.XML.pathRecusosFXML;
import utilidades.autocompletar.TextBoxAutoCompletar;
import utilidades.dialog.OptionPane;
import utilidades.number.DateTextField;
import utilidades.number.FloatTextField;
import utilidades.number.IntegerTextField;
import utilidades.number.PorcentajeTextField;
import utilidades.number.MonedaTextField;

/**
 *
 * @author silvi sigo??? acomodando eso o te doy a vos la pc?
 */
public class RegistrarEncomienda extends VentanaModal {

    @FXML
    private ComboBox<Agencia> empresaEmisora;
    @FXML
    private IntegerTextField nroGuia;
    @FXML
    private DateTextField fecha;
    @FXML
    private RadioButton envioADomicilio;
    @FXML
    private RadioButton entregaEnDeposito;
    @FXML
    private RadioButton retiroDeDomicilio;
    @FXML
    private RadioButton cobroRevertido;
    //campos servicio
    @FXML
    private ComboBox<TipoEncomienda> tipoServicio;
    @FXML
    private ComboBox<String> caracteristicas;
    @FXML
    private MonedaTextField precio;
    @FXML
    private PorcentajeTextField descuento;
    @FXML
    private PorcentajeTextField recargo;
    @FXML
    private MonedaTextField totalServicio;
    @FXML
    private TextArea observaciones;
    //Cliente remitente
    @FXML
    private ClienteComp clienteR;
    //Lugar Remitente
    @FXML
    private LugarComp lugarR;
    //Cliente destinatario
    @FXML
    private ClienteComp clienteD;
    //Lugar destinatario
    @FXML
    private LugarComp lugarD;
    //encomienda    
    private Encomienda encomiendaView = new Encomienda();
    private BeanPathAdapter<Encomienda> encomiendaPA = new BeanPathAdapter(encomiendaView);
    ValidatorFactory validatorFactory = javax.validation.Validation.buildDefaultValidatorFactory();
    Validator validator = validatorFactory.getValidator();

    public RegistrarEncomienda(Stage ventanaPadre, String titulo, int x, int y) {
        super(ventanaPadre, titulo, x, y);
        init();

    }

    public void init() {
        try {

            this.encomiendaView.setFechaRecepcion(new Date());

            this.setClientes();
            this.setAgencias();
            this.setTipoServicios();
            this.escuchadorCobroRevertido();
            
            this.totalServicio.numberProperty().bind(this.precio.numberProperty().subtract(this.descuento.numberProperty().multiply(this.precio.numberProperty())).add(this.recargo.numberProperty().multiply(this.precio.numberProperty())));
            


            //linqueo interfaz con bean
            this.bindingInterfazConEncomienda();


        } catch (NoSuchMethodException ex) {
            Logger.getLogger(RegistrarEncomienda.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

    private void bindingInterfazConEncomienda() throws NoSuchMethodException {

        this.encomiendaPA.bindBidirectional("entregaEnDeposito", this.envioADomicilio.selectedProperty());
        this.encomiendaPA.bindBidirectional("envioADomicilio", this.entregaEnDeposito.selectedProperty());
        this.encomiendaPA.bindBidirectional("retiroADomicilio", this.retiroDeDomicilio.selectedProperty());
        this.encomiendaPA.bindBidirectional("cobroRevertido", this.cobroRevertido.selectedProperty());
        this.encomiendaPA.bindBidirectional("observaciones", this.observaciones.textProperty());
        this.encomiendaPA.bindBidirectional("fechaRecepcion", this.fecha.dateProperty(), Date.class);
        this.encomiendaPA.bindBidirectional("caracteristica", this.caracteristicas.valueProperty(), String.class);
        //this.encomiendaPA.bindBidirectional("tipoDeServicio", this.tipoServicio.valueProperty(), TipoEncomienda.class);
        this.encomiendaPA.bindBidirectional("precio", this.precio.numberProperty());
        this.encomiendaPA.bindBidirectional("descuento", this.descuento.numberProperty());
        this.encomiendaPA.bindBidirectional("recargo", this.recargo.numberProperty());
        this.encomiendaPA.bindBidirectional("total", this.totalServicio.numberProperty());

    }

    public void cancelarEvent(ActionEvent event) {
        this.close();
    }

    public void guardarEvent() throws NoSuchMethodException, IOException {
        Lugar lugarRemitente = this.lugarR.getLugar();
        Cliente clienteRemitente = this.clienteR.getCliente();
        Lugar lugarDestinatario = this.lugarD.getLugar();
        Cliente clienteDestinatario = this.clienteD.getCliente();


        if (validar()) {


            //verifico si el domicilio no fue cambiado, de ser cambiado tengo q setear el id a null para poder guardar un domic nuevo
            if (lugarRemitente.getId() != null) {
                if (!lugarRemitente.esSimilar(GestorCliente.getInstance().buscarLugar(lugarRemitente.getId()))) {
                    lugarRemitente.setId(null);
                }
            }
            //verifico si el domicilio no fue cambiado, de ser cambiado tengo q setear el id a null para poder guardar un domic nuevo
            if (lugarDestinatario.getId() != null) {
                if (!lugarDestinatario.esSimilar(GestorCliente.getInstance().buscarLugar(lugarDestinatario.getId()))) {
                    lugarDestinatario.setId(null);
                }
            }



            this.encomiendaView.setEmisor(clienteRemitente);
            this.encomiendaView.setOrigen(lugarRemitente);
            this.encomiendaView.setReceptor(clienteDestinatario);
            this.encomiendaView.setDestino(lugarDestinatario);
            
           

            GestorEncomienda.getInstance().guardarEncomienda(encomiendaView);
            
            String[] textoBotones = {"Si", "No"};

            int nroBotonApretado = OptionPane.showOptionDialog("Repartidor creado", "La encomienda ha sido guardada\n ¿desea registrar otra encomienda?", null, OptionPane.SUCESS_MESSAGE, textoBotones);

                if (nroBotonApretado == 0) {
              
                    new RegistrarEncomienda(ventanaPadre,"Registrar encomienda",900,700);
                }
                //

                this.close();
        }
 

        //this.close();
    }

    private void setAgencias() {


        this.empresaEmisora.setItems(FXCollections.observableArrayList(GestorAgencia.getInstance().findAll()));
        empresaEmisora.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Agencia>() {
            @Override
            public void changed(ObservableValue<? extends Agencia> ov, Agencia t, Agencia newAgencia) {

                if (newAgencia != null) {
                    if (newAgencia instanceof Interna) {
                        Interna interna = (Interna) newAgencia;
                        nroGuia.setText("" + (interna.getCantidadEncomiendas() + 1));
                        nroGuia.setEditable(false);
                    } else {
                        if (newAgencia instanceof Externa) {
                            Externa externa = (Externa) newAgencia;
                            nroGuia.setText("");
                            nroGuia.setEditable(true);
                        }
                    }
                }

            }
        });
    }

    private void setTipoServicios() {


        this.tipoServicio.setItems(FXCollections.observableArrayList(GestorTipoServicio.getInstance().findAllTipoEncomienda()));
        this.tipoServicio.getSelectionModel().select(0);

        tipoServicio.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TipoEncomienda>() {
            @Override
            public void changed(ObservableValue<? extends TipoEncomienda> ov, TipoEncomienda t, TipoEncomienda newTipoEncomienda) {

                if (newTipoEncomienda != null) {

                    TipoEncomienda tipoServEncomienda = (TipoEncomienda) newTipoEncomienda;
                    precio.setText(tipoServEncomienda.getPrecio() + "");
                    encomiendaView.setTipoDeServicio(tipoServEncomienda);

                }

            }
        });
    }

    @Override
    URL getURLFXML() {
        return pathRecusosFXML.class.getResource("RegistrarEncomienda.fxml");
    }

    public void buscarLugarR(ActionEvent event) throws IOException {
        if (this.clienteR.getCliente() != null) {
            new ABMLugarPersonalFrecuente(this.clienteR.getCliente(), this, "Lugares personales del cliente", 800, 700);
        } else {
            OptionPane.showOptionDialog("Informacion", "Debe seleccionar un cliente para buscar sus lugares frecuentes", "", OptionPane.INFORMATION_MESSAGE, null);

        }
    }

    public void buscarLugarD(ActionEvent event) throws IOException {
        if (this.clienteR.getCliente() != null) {
            new ABMLugarPersonalFrecuente(this.clienteD.getCliente(), this, "Lugares personales del cliente", 800, 700);
        } else {
            OptionPane.showOptionDialog("Informacion", "Debe seleccionar un cliente para buscar sus lugares frecuentes", "", OptionPane.INFORMATION_MESSAGE, null);

        }
    }

    public void buscarClienteD(ActionEvent event) throws IOException {
        //abm de cliente
    }

    public void buscarClienteR(ActionEvent event) throws IOException {
        //abm de cliente
    }

    public void setLugarPersonalFrecuenteR(Lugar lugarSeleccionado) {
        lugarR.cambiarLugar(lugarSeleccionado);
    }

    private void setClientes() {
        this.lugarR.getAlias().addListener(new ChangeListener<Lugar>() {
            @Override
            public void changed(ObservableValue<? extends Lugar> selected, Lugar oldValue, Lugar newValue) {
                if (newValue != null) {
                    lugarR.cambiarLugar(newValue);
                } else {
                    if (clienteR.getCliente() != null) {
                        lugarR.cambiarLugar(clienteR.getCliente().getDomicilio());
                    } else {
                        lugarR.cambiarLugar(new Domicilio());
                    }
                }

            }
        });


        this.clienteR.getClienteProperty().addListener(new ChangeListener<Cliente>() {
            @Override
            public void changed(ObservableValue<? extends Cliente> ov, Cliente t, Cliente clienteNew) {

                //si selecciono un cliente
                if (clienteNew != null) {
                    if (!cobroRevertido.isSelected()) {
                        descuento.setValue(clienteNew.getPorcentajeDescuento());
                    }
                    Domicilio d = clienteNew.getDomicilio();
                    if (d != null) {
                        lugarR.cambiarLugar(d);
                    } else {
                        lugarR.cambiarLugar(new Domicilio());
                    }
                    List lugares = clienteNew.getLugaresPersonalesFrecuentes();
                    if (!lugares.isEmpty()) {
                        lugarR.setLugaresAlias(lugares);
                    } else {
                        lugarR.setLugaresAlias(new ArrayList());
                    }
                    //si quiero seleccionar un cliente pero no existe cliente== null
                } else {
                    lugarR.setLugaresAlias(new ArrayList());
                    lugarR.cambiarLugar(new Domicilio());
                }


            }
        });


        this.lugarD.getAlias().addListener(new ChangeListener<Lugar>() {
            @Override
            public void changed(ObservableValue<? extends Lugar> selected, Lugar oldValue, Lugar newValue) {
                if (newValue != null) {
                    lugarD.cambiarLugar(newValue);
                } else {
                    if (clienteD.getCliente() != null) {
                        lugarD.cambiarLugar(clienteD.getCliente().getDomicilio());
                    } else {
                        lugarD.cambiarLugar(new Domicilio());
                    }
                }
            }
        });

        this.clienteD.getClienteProperty().addListener(new ChangeListener<Cliente>() {
            @Override
            public void changed(ObservableValue<? extends Cliente> ov, Cliente t, Cliente clienteNew) {

                //si selecciono un cliente
                if (clienteNew != null) {
                    if (cobroRevertido.isSelected()) {
                        descuento.setValue(clienteNew.getPorcentajeDescuento());
                    }
                    Domicilio d = clienteNew.getDomicilio();
                    if (d != null) {
                        lugarD.cambiarLugar(d);
                    } else {
                        lugarD.cambiarLugar(new Domicilio());
                    }
                    List lugares = clienteNew.getLugaresPersonalesFrecuentes();
                    if (!lugares.isEmpty()) {
                        lugarD.setLugaresAlias(lugares);
                    } else {
                        lugarD.setLugaresAlias(new ArrayList());
                    }

                    //si quiero seleccionar un cliente pero no existe cliente== null
                } else {

                    lugarD.cambiarLugar(new Domicilio());
                    lugarD.setLugaresAlias(new ArrayList());
                }

            }
        });
    }

    private boolean validar() {
        String errorText = "";

        if (this.empresaEmisora.getSelectionModel().isEmpty()) {
            errorText = errorText + "* Seleccione una Empresa Emisora    \n";
        }else{

        Agencia agencia = this.empresaEmisora.getValue();
        if (agencia instanceof Interna) {
            this.encomiendaView.setId(this.nroGuia.getText());
        } else {
         
            this.encomiendaView.setId(agencia.getCuit() + "_" + this.nroGuia.getText());
        }
        
        if (GestorEncomienda.getInstance().findById(this.encomiendaView.getId()) != null) {

            errorText = errorText + "* Ya existe el nro guia para la agencia\n";
        }
        
        }

       

        if (this.nroGuia.getText().trim().isEmpty()) {
            errorText = errorText + "* Coloque el numero de Guia          \n";
        }
        if (!this.clienteR.validar()) {
            errorText = errorText + "* Seleccione un Cliente Remitente    \n";
        }
        if (!this.clienteD.validar()) {
            errorText = errorText + "* Seleccione un Cliente Destinatario \n";
        }
        if (!this.lugarR.validar()) {
            errorText = errorText + "* Verifique el Lugar del Remitente   \n";
        }
        if (!this.lugarD.validar()) {
            errorText = errorText + "* Verifique el Lugar del Destinatario \n";
        }




        if (!errorText.isEmpty()) {
            OptionPane.showOptionDialog("Errores al crear la encomienda", errorText, "", OptionPane.ERROR_MESSAGE, null);
        }


        return errorText.trim().isEmpty();
    }

    public void actualizarLugarDeCliente(Cliente c, Lugar l) {
      

        List listLugares=c.getLugaresPersonalesFrecuentes();
        if (this.clienteD.getCliente() == c) {
            lugarD.setLugaresAlias(listLugares);
            if(l!=null){
            lugarD.getAlias().setText("");
            lugarD.cambiarLugar(l);
            }
        } else {
            if (this.clienteR.getCliente() == c) {
                lugarR.setLugaresAlias(listLugares);
                 if(l!=null){
                lugarR.getAlias().setText("");
                lugarR.cambiarLugar(l);
                 }
            }
        }
        
    }

    public void escuchadorCobroRevertido() {
        this.cobroRevertido.selectedProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue o, Object oldVal,
                    Object newVal) {
                if (!cobroRevertido.isSelected()) {
                   // System.out.println("PAGA EL REMITENTE");
                    if (clienteR.getCliente() != null) {
                        descuento.setValue(clienteR.getCliente().getPorcentajeDescuento());
                    } else {
                        descuento.setValue(Float.valueOf(0));
                    }
                } else {
                    if (clienteD.getCliente() != null) {
                    //    System.out.println("PAGA EL DESTINATARIO");
                        descuento.setValue(clienteD.getCliente().getPorcentajeDescuento());
                    } else {
                        descuento.setValue(Float.valueOf(0));
                    }
                }
            }
        });

    }
}
